package com.shop.servlet.filter;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.api.openfeign.client.UserClient;
import com.api.openfeign.dto.UserDto;
import com.shop.common.enums.ExceptionEnum;
import com.shop.common.exception.OperationException;
import com.shop.common.response.ExceptionResponse;
import com.shop.servlet.model.LoginUser;
import com.shop.security.utils.JwtUtils;




import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.operator.OperatorStreamException;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;


import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;

@Slf4j

//@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtils jwtUtils;
    // 注入公共接口（具体实现由业务模块提供）

    /**
     * 从请求头中获取令牌
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(JwtUtils.HEADER_TOKEN);
        if (token != null && token.startsWith(JwtUtils.TOKEN_PREFIX)) {
            return token.substring(7);
        }
        return null;
    }
    @Autowired
    private UserClient userClient;
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        log.info("JWT Authentication Filter");
        try {
            String jwt = getToken(request);
            if(jwt != null && jwtUtils.validateToken(jwt)) {
                String username = jwtUtils.getUsernameFromToken(jwt);
                log.info("Username : {}", username);
                UserDto userDto = userClient.username(username);
                //LoginUser userDetails = new LoginUser(userDto.getId(),userDto.getUsername(),userDto.getEmail(),userDto.getPassword());
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                // 设置认证信息
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities()
                );
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }else {
                log.info("JWT Authentication Filter Failed {}",request.getRequestURI());
//            response.setCharacterEncoding("UTF-8");
//            response.setContentType("application.yml/json");
//            response.setStatus(HttpStatus.UNAUTHORIZED.value());

            }
        } catch (Exception e) {
            log.error("Cannot set user authentication: {}",e.getMessage());
            sendErrorResponse(response, ExceptionEnum.TOKEN_BLACKLISTED);
        }
        filterChain.doFilter(request, response);
    }
    // 手动构建错误响应
    private void sendErrorResponse(HttpServletResponse response, ExceptionEnum exceptionEnum) throws IOException {
        // 1. 设置响应状态码和内容类型
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());

        // 2. 构建自定义响应对象
        ExceptionResponse errorResponse = new ExceptionResponse(
                exceptionEnum.getCode(),  // 业务状态码
                exceptionEnum.getMsg(),  // 提示信息
                null  // 数据字段（无数据时为null）
        );

        // 3. 使用 FastJSON 序列化响应对象为JSON字符串
        // 序列化时保留 null 字段
        String jsonResponse = JSON.toJSONString(
                response,
                SerializerFeature.WriteMapNullValue  // 关键配置：保留 null 字段
        );

        // 4. 写入响应体
        response.getWriter().write(jsonResponse);
    }
}
